/*
 * @Author: 瞿旺兴 18774621495@163.com
 * @Date: 2022-05-25 11:25:45
 * @LastEditors: 瞿旺兴 18774621495@163.com
 * @LastEditTime: 2022-06-23 09:42:27
 * @FilePath: \nien-vue3-admin\src\utils\websocket.ts
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
import { resetUserPwd } from '@/api/system/user';
import { ElMessage } from 'element-plus'

class createWebsocket {
  constructor(public url:string) {
    // this.init()
  }

  _ws:WebSocket;

  get status(){
    let readyState = this._ws?.readyState || undefined
    if(this.reconnecting || readyState === 0){
      return 'CONNECTING'
    }
    switch (readyState) {
      case 1:
        return 'OPEN'
      case 2:
        return 'CLOSING'
      case 3:
      default:
        return 'CLOSED'
    }
  }

  // 正在连接时发送的消息
  protected queue = [];

  // 重连次数
  protected reconnectTime = 3;

  protected lockReconnect = true;

  protected reconnecting = false;

  protected timer = null;

  init() {
    if (!('WebSocket' in window)) {
      return ElMessage.warning('浏览器不支持Websocket！')
    }
    try {
      this._ws = new WebSocket(this.url)
      this._ws.onopen = (e) => this.handleOpen(e)
      this._ws.onclose = (e) => this.handleClose(e)
      this._ws.onmessage = (e) => this.handleMessage(e)
      this._ws.onerror = (e) => this.handleError(e)
    } catch (e) {
      if (this.reconnectTime > 0) {
        this.reconnect()
      } else {
        this.resetReconnectStatus()
        ElMessage.error('Websocket连接失败！')
        throw new Error(e)
      }
    }
  }

  // 重置重连状态
  protected resetReconnectStatus() {
    this.reconnecting = false
    this.reconnectTime = 3
  } 

  protected reconnect() {
    if (this.lockReconnect) {
      return
    }
    console.log('ws重连中。。。')
    this.reconnectTime--
    this.reconnecting = true
    this.lockReconnect = true
    clearTimeout(this.timer)
    this.timer = setTimeout(() => {
      this.init()
      this.lockReconnect = false
    }, 3000)
  }

  protected handleOpen(event) {
    console.log('ws已连接！！！,')
    this.resetReconnectStatus()
    if (this.status !== 'OPEN') return
    
    for (const p of this.queue) {
      this._ws.send(p)
    }
    this.queue = []
    if (this.open) {
      this.open(event)
    }
  }

  protected handleClose(event) {
    console.log('ws连接关闭！！！')
    this.reconnect()
    if (this.close) {
      this.close(event)
    }
  }

  protected handleMessage(event) {
    if (this.message) {
      this.message(event)
    }
  }

  protected handleError(event) {
    console.log('ws连接失败！！！')
    this.reconnect()
    if (this.error) {
      this.error(event)
    }
  }

  send(params) {
    if (this.status === 'OPEN') {
      this._ws.send(params)
    } else if (this.status === 'CONNECTING') {
      // 如果ws在连接或重连中就加入队列等待
      this.queue.push(params)
    } else {
      this.reconnecting = true
      this.queue.push(params)
      this.init()
    }
  }

  open:(event) => void

  close:(event) => void

  message:(event) => void
  
  error:(event) => void
}

export default createWebsocket